﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HRM.Model;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Windows;
using GalaSoft.MvvmLight.Messaging;
using HRM.Helper;
using GalaSoft.MvvmLight.Ioc;

namespace HRM.ViewModel
{
    public class ViewModelGeneric<T> : ViewModelBase where T : Entity, new()
    {
        protected readonly NguoiSuDung _user;
        protected readonly IEntityService<T> _service;

        public ViewModelGeneric(IEntityService<T> service)
        {
            _service = service;
            _user = SimpleIoc.Default.GetInstance<NguoiSuDung>();
            Refresh();
        }

        private List<T> _list;

        public List<T> ListEntities
        {
            get { return _list; }
            set
            {
                if (_list != value)
                {
                    _list = value;
                    RaisePropertyChanged("ListEntities");
                }
            }
        }

        protected T _selectedItem;

        public virtual T SelectedItem
        {
            get
            {
                if (_selectedItem == null) _selectedItem = new T();
                return _selectedItem;
            }
            set
            {
                if (_selectedItem != value)
                {
                    _selectedItem = value;
                    RaisePropertyChanged("SelectedItem");
                }
            }
        }

        #region Property Update or Add Item

        protected bool _addmode = true;

        public virtual bool AddMode
        {
            get { return _addmode; }
            set
            {
                if (_addmode != value)
                {
                    _addmode = value;
                    if (value)
                    {
                        SelectedItem = new T();
                    }
                    RaisePropertyChanged("AddMode");
                }
            }
        }

        protected bool _updateMode = false;

        public virtual bool UpdateMode
        {
            get { return _updateMode; }
            set
            {
                if (_updateMode != value)
                {
                    _updateMode = value;
                    RaisePropertyChanged("UpdateMode");

                }
            }
        }

        #endregion

        #region Property Paging DataGrid

        private int _pageIndex = 1;

        public int PageIndex
        {
            get { return _pageIndex; }
            set
            {
                if (_pageIndex != value)
                {
                    _pageIndex = value;
                    RaisePropertyChanged("PageIndex");
                }
            }
        }

        private int _numberOfPages = 1;

        public int NumberOfPages
        {
            get { return _numberOfPages; }
            set
            {
                if (_numberOfPages != value)
                {
                    _numberOfPages = value;
                    RaisePropertyChanged("NumberOfPages");
                }
            }
        }

        private int _pageSize = 10;

        public int PageSize
        {
            get { return _pageSize; }
            set
            {
                if (_pageSize != value)
                {
                    _pageSize = value;
                    RaisePropertyChanged("PageSize");
                }
            }
        }

        private int _totalItems = 0;

        public int TotalItems
        {
            get { return _totalItems; }
            set
            {
                if (_totalItems != value)
                {
                    _totalItems = value;
                    RaisePropertyChanged("TotalItems");
                }
            }
        }

        #endregion

        #region Command

        public RelayCommand NextPageCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    if (PageIndex < NumberOfPages)
                    {
                        PageIndex++;
                        ListEntities = _service.GetPaging(PageIndex, PageSize);
                    }
                });
            }
        }

        public RelayCommand PreviosPageCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    if (PageIndex > 1)
                    {
                        PageIndex--;
                        ListEntities = _service.GetPaging(PageIndex, PageSize);
                    }
                });
            }
        }

        public RelayCommand LastPageCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    PageIndex = NumberOfPages;
                    ListEntities = _service.GetPaging(PageIndex, PageSize);
                });
            }
        }

        public RelayCommand FirstPageCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    PageIndex = 1;
                    ListEntities = _service.GetPaging(PageIndex, PageSize);
                });
            }
        }

        public RelayCommand RefreshCommand
        {
            get { return new RelayCommand(Refresh); }
        }

        public RelayCommand<bool> CheckAllCommand
        {
            get
            {
                return new RelayCommand<bool>((obj) =>
                {
                    if (obj)
                    {
                        foreach (var item in ListEntities)
                        {
                            item.IsChecked = true;
                        }
                    }
                    else
                    {
                        foreach (var item in ListEntities)
                        {
                            item.IsChecked = false;
                        }
                    }
                });
            }
        }

        public RelayCommand DeleteListCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    var list = ListEntities.FindAll(x => x.IsChecked == true);
                    if (list.Count == 0) return;

                    if (MessageBox.Show(string.Format("Xóa {0} bản ghi?", list.Count), "Xác nhận", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel) == MessageBoxResult.OK)
                    {
                        if (_service.DeleteList(list))
                        {
                            Refresh();
                            Messenger.Default.Send(new StatusMessage(list.Count.ToString() + " bản ghi đã được xóa", 3000, StatusType.Done));
                        }
                        else
                        {
                            Messenger.Default.Send(StatusMessage.DatabaseErrorMessage());
                        }
                    }
                }, () => _user.GetPermisstion);
            }
        }

        public virtual RelayCommand SaveCommand
        {
            get
            {
                return new RelayCommand(() =>
                {
                    if (AddMode)
                    {
                        _service.Add(SelectedItem);
                        Messenger.Default.Send(new StatusMessage("Đã thêm xong.", 3000, StatusType.Done));
                    }
                    else if (UpdateMode)
                    {
                        _service.Update(SelectedItem);
                        Messenger.Default.Send(new StatusMessage("Thay đổi thành công.", 3000, StatusType.Done));
                    }
                    Refresh();
                }, () => _user.GetPermisstion);
            }
        }

        public RelayCommand<T> DeleteCommand
        {
            get
            {
                return new RelayCommand<T>((pb) =>
                {
                    if (MessageBox.Show(string.Format("Bạn có chắc chắn muốn xóa không?"), "Xác nhận", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel) == MessageBoxResult.OK)
                    {
                        if (_service.Delete(pb))
                        {
                            Messenger.Default.Send(new StatusMessage("Đã xóa thành công", 3000, StatusType.Done));
                            Refresh();
                        }
                    }
                }, (pb) => _user.GetPermisstion);
            }
        }

        #endregion

        public virtual void Refresh()
        {
            ListEntities = _service.GetPaging(PageIndex, PageSize);
            NumberOfPages = _service.GetNumberOfPages(PageSize);
            TotalItems = _service.GetAll().Count;
        }
    }
}
